﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Assertions;

namespace Nirvana
{
    /// <summary>
    /// 制作Minimap，原始图创建好后，可以给美术修改
    /// </summary>
    [RequireComponent(typeof(Camera))]
    [ExecuteInEditMode]
    [AddComponentMenu("Nirvana/Render/Minimap Camera")]
    public sealed class MinimapCamera : MonoBehaviour
    {
        private static MinimapCamera m_instance;
        public static MinimapCamera Instance
        {
            get
            {
                return m_instance;
            }
        }

        [SerializeField]
        [Tooltip("The map texture.")]
        private Texture2D mapTexture;
        [Tooltip("The minimap texture width.")]
        [SerializeField]
        private int mapTextureWidth = 512;
        [SerializeField]
        [Tooltip("The minimap texture height.")]
        private int mapTextureHeight = 512;

        [Tooltip("The scene camera.")]
        [SerializeField]
        private Camera sceneCamera;
        [SerializeField]
        [Tooltip("The ignore list for take texture.")]
        private GameObject[] ignoreList;
        private Camera _camera;
        private Vector2 originPos;
        private float orthographicSize;
        private float ratio;
 
        public Texture2D MapTexture
        {
            get
            {
                return this.mapTexture;
            }
            set
            {
                this.mapTexture = value;
            }
        }

        public int MapTextureWidth
        {
            get
            {
                return this.mapTextureWidth;
            }
        }

        public int MapTextureHeight
        {
            get
            {
                return this.mapTextureHeight;
            }
        }

      

        private void Awake()
        {
            Assert.IsNull<MinimapCamera>(m_instance);
            m_instance = this;
            this._camera = GetComponent<Camera>();
            Assert.IsNotNull<Camera>(this._camera);
            Assert.IsTrue(this._camera.orthographic);
            this._camera.enabled = false;
            orthographicSize = this._camera.orthographicSize;
            this.ratio = this.mapTextureHeight*1f / this.mapTextureWidth;
            Vector3 pos = this._camera.transform.position;
            originPos = new Vector2(pos.x - orthographicSize, pos.z - orthographicSize);

        }

#if UNITY_EDITOR
        private void Update()
        {
            if(!Application.isPlaying && this.sceneCamera != null)
            {
                float y = this.sceneCamera.transform.rotation.eulerAngles.y;
                transform.rotation = Quaternion.Euler(90, y, 0);
            }
        }
#endif

        private void OnDestroy()
        {
            m_instance = null;
        }

        public void SetIgnoreListEnabled(bool enabled)
        {
            if (this.ignoreList == null)
            {
                return;
            }
            foreach (GameObject gameObject in this.ignoreList)
            {
                gameObject.SetActive(enabled);
            }
        }

        public Vector2 TransformWorldToUV(Vector3 pos)
        {
            float x = (pos.x - originPos.x) / (2f * orthographicSize);
            float z = (pos.z - originPos.y) / (2f * orthographicSize);
            x -= 0.5f;
            z -= 0.5f;
            Vector3 vector = new Vector3(x, pos.y, z);
            float y = transform.rotation.eulerAngles.y;
            vector = Quaternion.Euler(0, -y, 0) * vector;
            vector.x *= this.ratio;

            return new Vector2(vector.x, vector.z);
        }

        public Vector3 TransformUVToWorld(Vector2 uv)
        {
            uv.x /= this.ratio;
            Vector3 vector = new Vector3(uv.x, 0, uv.y);
            float y = transform.rotation.eulerAngles.y;
            vector = Quaternion.Euler(0, y, 0) * vector;
            vector.x += 0.5f;
            vector.z += 0.5f;
            float x = vector.x * 2f * this.orthographicSize + this.originPos.x;
            float z = vector.z * 2f * this.orthographicSize + this.originPos.y;

            return new Vector3(x, vector.y, z);
        }

    }
}

